package com.cgah

import com.cgah.exceptions.BidNotFoundException
import com.icegreen.greenmail.util.GreenMailUtil

class BidServiceTests extends AbstractIntegrationTest {
    Customer bidder;
    Customer seller;
    Listing listing;
    Listing oldListing;

    def mailService
    def greenMail
    def emailService

    public void setUp() {

        super.setUp()

        seller = new Customer(username: "seller",
                emailAddress: "seller@seller.com",
                createdDate: new Date(),
                password: "12312312",
                enabled: true);

        bidder = new Customer(username: "bidder",
                emailAddress: "bidder@bidder.com",
                createdDate: new Date(),
                password: "12312312",
                enabled: true);


        listing = new Listing(createdDateTime: new Date(),
                description: "asdf",
                seller: seller,
                startingBidPrice: 11.0f,
                name: "test",
                endDateTime: (new Date()) + 1);

        oldListing = new Listing(createdDateTime: new Date(),
            description: "expired",
            seller: seller,
            startingBidPrice: 11.0f,
            name: "testexpired",
            endDateTime: (new Date()) + 1);

        seller.save(flush: true);
        bidder.save(flush: true);
        listing.save(flush: true);
        oldListing.save(flush:true);


        assertTrue(Listing.list().size() >= 2);
        assertTrue(Customer.list().size() >= 2);

/*
        params.put('listing.id', listing.id);
        params.put('amount', listing.startingBidPrice + 1.0f)
*/
    }

    public void tearDown() {
        greenMail.deleteAllMessages()
        super.tearDown()
    }

    //S-3: Create a Grails service method that supports bidding on a listing (integration test)
    void testCreate_ReturnsCorrectObject() {

        params.put('listing.id', listing.id);
        params.put('amount', listing.startingBidPrice + 1.0f)

        def bidService = new BidService();

        def bid = bidService.create(params)
        assertNotNull(bid);
    }

    //S-3: Create a Grails service method that supports bidding on a listing (integration test)
    void testSave_ObjectIsPersisted() {
        params.put('listing.id', listing.id);
        params.put('amount', listing.startingBidPrice + 1.0f)

        def bidService = new BidService();

        def bid = bidService.create(params)
        assertNotNull(bid);

        bid = bidService.save(params, bidder.id);
        // on save, the object gets persisted to the DB, hence there is an ID.
        // this should be all we need to do, since the ID is only ever assigned once the object is persisted
        // successfully to the DB AND in theory, no one should be able to set the ID.
        assertNotNull(bid.id);
    }

    // C-4: When a listing completes it can no longer accept any more bids.  Verify this by testing through the service method created for S-3 (integration test).
    void testSave_expiredListing() {
        oldListing.endDateTime = new Date() - 1
        params.put('listing', oldListing);
        params.put('amount', oldListing.startingBidPrice + 1.0f)

        def bidService = new BidService();

        def bid = bidService.create(params)
        assertNotNull(bid);
        try {
            bid = bidService.save(params, bidder.id);
            fail("exception expected")
        } catch (BidNotFoundException e) {
            assertNotNull(e);
            assertEquals(e.message, "Cannot save bid.  Listing has expired");
        }
    }

    // S-5: The Grails service method for S-3 must validate the bidders username and password before creating the bid (integration test)
    void testCreate_invalidUserNamePassword() {
        params.put('listing.id', listing.id);
        params.put('amount', listing.startingBidPrice + 1.0f)

        def bidService = new BidService();

        try {
            def bid = bidService.save(bidService.create(params), "jane", "blow");
            fail("exception is suppose to be thrown")
        } catch (BidNotFoundException bnf) {
            assertTrue("Sccuess", true);
        }

    }

    // S-5: The Grails service method for S-3 must validate the bidders username and password before creating the bid (integration test)
    void testCreate_correctUserNamePassword() {
        params.put('listing.id', listing.id);
        params.put('amount', listing.startingBidPrice + 1.0f)

        def bidService = new BidService();

        try {

             assertNotNull("Sccuess",  bidService.save(bidService.create(params), bidder.username, bidder.password));
        } catch (BidNotFoundException bnf) {
            fail("exception was not expected");
        }

    }

    // C-6: Raise your grade on any one assignment by a full letter grade by proving requirements C1 and C3 via integration tests (integration test).
    void testSendEmail_onSuccessfulBid_C6_C1() {
        params.put('listing.id', listing.id);
        params.put('amount', listing.startingBidPrice + 1.0f)
        params.put('customer', bidder);

        def bidService = new BidService();
        bidService.emailService = new  EmailService();
        bidService.emailService.mailService = mailService
        try {
            assertNotNull("Sccuess", bidService.save(bidService.create(params), bidder.username, bidder.password));
        } catch (BidNotFoundException bnf) {
            fail("exception was not expected");
        }

        assertNotNull(greenMail.getReceivedMessages());
        def message = greenMail.getReceivedMessages()[0]
        assertNotNull(GreenMailUtil.getBody(message))
/*
        assertEquals(mail.from, GreenMailUtil.getAddressList(message.from))
        assertEquals(mail.subject, message.subject)
*/
    }


}
